package example

import (
	"context"
	"fmt"
	"go-source-learn/src/util/goutil"
	"sync/atomic"
	"time"
)

func print() {
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer cancel()

	time := 500
	nos := make(chan int, time>>2)
	defer close(nos)
	var counter int64 = 0
	for i := 0; i < time; i++ {
		go func(pId int) {
			for n := 0; n < 10; n++ {
				iFin := <-nos
				atomic.AddInt64(&counter, 1)
				fmt.Printf("I am Goroutine:%d no:%d times:%d \n", pId, iFin+1, counter)
				nos <- (iFin + 1) & 3
			}
		}(i)
	}
	nos <- 0

	select {
	case <-ctx.Done():
		fmt.Println("time out!!!")
		return
	}
}

type Token struct{}

func worker(id int, ch chan Token, nextCh chan Token) {
	ticker := time.NewTicker(2 * time.Millisecond)
	for range ticker.C {
		token := <-ch
		fmt.Printf("Goroutine:%d no:%d\n", goutil.GoID(), id+1) // id从1开始
		nextCh <- token
	}
}

func advance() {
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer cancel()

	chs := []chan Token{make(chan Token), make(chan Token), make(chan Token), make(chan Token)} // 创建4个worker
	for i := 0; i < 4; i++ {
		go worker(i, chs[i], chs[(i+1)&3])
	}
	//首先把令牌交给第一个worker
	chs[0] <- struct{}{}

	select {
	case <-ctx.Done():
		fmt.Println("time out!!!")
		return
	}
	////select {}
	//time.Sleep(1 * time.Second)
}
